package services;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;

import models.Acudiente;
import models.Colegio;
import models.Curso;
import models.Estudiante;
import models.Grado;
import models.Materia;
import models.MateriaCurso;
import models.Matricula;
import models.Persona;
import models.Profesor;
import models.TienePersona;
import play.cache.Cache;
import actors.UserCreator;

public class ColegioSrv {

	public static Colegio getColegio(final Long idColegio) {

		try {
			return Cache.getOrElse("idColegio=" + idColegio,
					new Callable<Colegio>() {
						@Override
						public Colegio call() throws Exception {
							Colegio c = DAO.find(Colegio.class, idColegio);
							DAO.detach(c);
							return c;
						}
					}, 86400000);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return DAO.find(Colegio.class, idColegio);
	}

	public static List<Colegio> getColegios() {

		return DAO.execute("SELECT c FROM Colegio c", -1);
	}

	public static List<Materia> getMateriasColegio(Long idColegio) {
		List<Materia> m = DAO.execute(
				"SELECT m FROM Materia m WHERE m.idColegio=:idColegio", -1,
				"idColegio", idColegio);
		return m;
	}

	public static List<Grado> getGradosColegio(Long idColegio) {
		return DAO.executeNamed("getGradosColegio", -1, "idColegio", idColegio);
	}

	public static List<Estudiante> getEstudiantes(Long idColegio, String filter) {
		Long idCalendarioAcademico = ColegioSrv.getColegio(idColegio)
				.getIdCalendarioAcademicoActual();
		List<Object[]> res = DAO.executeNamed(Estudiante.ESTUDIANTES, 50,
				"idColegio", idColegio, "nombre", "%" + filter.toLowerCase()
						+ "%", "idCalendarioAcademico", idCalendarioAcademico,
				"idColegio", idColegio);
		List<Estudiante> estudiantes = new ArrayList<Estudiante>();
		for (Object[] estMat : res) {
			Estudiante e = (Estudiante) estMat[0];
			Matricula m = (Matricula) estMat[1];
			Acudiente a = (Acudiente) estMat[2];
			e.setMatricula(m);
			e.setAcudiente(a);
			estudiantes.add(e);
		}
		return estudiantes;
	}

	public static List<Curso> getCursosGrado(long idCalendarioAcademico,
			Long idGrado) {
		List<Curso> cursos = null;
		if (idGrado == -1)
			cursos = DAO.executeNamed(Curso.QUERY_CURSOS_PERIODO, -1,
					"idCalendarioAcademico", idCalendarioAcademico);
		else
			cursos = DAO.executeNamed(Curso.QUERY_CURSOS_GRADO, -1, "idGrado",
					idGrado, "idCalendarioAcademico", idCalendarioAcademico);
		return cursos;
	}

	public static List<Materia> getMateriasGrado(Long idGrado) {

		return DAO.executeNamed(Materia.MATERIAS_GRADO, -1, "idGrado", idGrado);
	}

	public static void newCurso(Curso c) {

		DAO.persist(c);
		DAO.flush();

	}

	public static List<MateriaCurso> getMateriasCurso(Long idCurso) {
		// mg.id_materia, 1, mc.id_profesor, per.nombres, per.apellidos
		List<Object[]> data = DAO.executeNamed(MateriaCurso.ASIGNATURAS_CURSO,
				-1, "idCurso", idCurso);
		List<MateriaCurso> mcs = new ArrayList<MateriaCurso>();
		for (Object[] oo : data) {
			MateriaCurso mc = new MateriaCurso();
			mc.setIdMateria(((Number) oo[0]).longValue());
			mc.setIdCurso(idCurso);
			System.out.println(oo[2]);
			if (oo[2] != null) {
				Profesor profe = new Profesor();
				profe.setId(((Number) oo[2]).longValue());
				Persona p = new Persona();
				System.out.println(oo[4]);
				p.setApellidos((String) oo[4]);
				p.setNombres((String) oo[3]);
				profe.setPersona(p);
				mc.setProfesor(profe);
			}
			mcs.add(mc);
		}
		return mcs;
	}

	public static void crearActorConUsuario(TienePersona actor) {
		if (actor.getId() == null) {
			Persona persona = actor.getPersona();
			if (persona.getId() == null) {
				Persona p = (Persona) DAO.query(Persona.class, 1,
						"tipoDocumento", persona.getTelefono(), "documento",
						persona.getDocumento());
				if (p != null) {
					persona.setId(p.getId());
				}
			}
			DAO.persist(actor);
			DAO.flush();
			UserCreator.createUser(actor);
		} else {
			ErrorManager.reportError(
					"están persistiendo actores que ya tienen ID", actor);
		}

	}

}
